<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content=initial-scale=1.0>
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>北京哈工科教机器人科技有限公司</title>
    <link rel="shortcut icon" href="favicon.ico">
    <link href="./css/element.min.css" rel="stylesheet">
    <link href="./css/style.css" rel="stylesheet">
    <script src="./js/vue.min.js"></script>
    <script src="./js/element.min.js"></script>
    <script src="./js/three.min.js"></script>
    <script src="./js/leap.min.js"></script>
    <script src="./js/leap-plugins-0.1.6.js"></script>
</head>

<body>
    <div id="app">
        <div class="pull-left height bgcoler1 width1">
            <img src="./images/LOGO.png" alt="">
            <img @click="restartleap()" src="./images/menu_04.png" title="restart">
            <!-- <img src="./images/inter.png" class="postion-absolute" alt=""> -->
        </div>
        <div class="pull-left height bgcoler2 width1">
            <img style="margin-top: 160px;" @click="leapbutton()" :src="menu" alt="">
        </div>
        <div class="pull-left height">
            <el-steps  :active="active" finish-status="success">
                <el-step title="检查LeapMotion服务器"></el-step>
                <el-step title="启动服务器"></el-step>
                <el-step title="启动动画"></el-step>
                <el-step title="检查串口"></el-step>
                <el-step title="启动完成"></el-step>
            </el-steps>
            <div class="pull-left">
                <img :src="leapCq" class="imgleft" alt="">
            </div>
            <div class="pull-right" id="leapThree">
            </div>
            <div class="clearfix"></div>
        </div>
        <div class="clearfix"></div>
        <audio v-show="false" id="song" controls preload="none" height="100" width="100" :src="song"></audio>
    </div>
</body>

</html>

<script>
    const serialport = require('serialport')

    function delay(time) {
        return new Promise((res, rej) => {
            setTimeout(() => {
                res()
            }, time)
        })
    }
    async function getport() {
        let pot = [];
        let ports = await serialport.list()
        //console.log(ports)
        for (let v of ports) {
            if (v.manufacturer === 'wch.cn') {
                pot.push(v.comName)
            }
        }
        return pot
    }

    function getserial(com) {
        return new serialport(com, {
            baudRate: 9600
        })

    }

    function getok(x) {
        x.on('open', () => {
            vm.ts('打开串口成功')
            if (this.active != 0) {
                vm.stortChuankou()

            }
        });
        x.on('data', (data) => {
            // console.log(data)
            if (data == "leapA") {
                vm.LeapMode = 1
            } else if (data == "leapB") {
                vm.LeapMode = 2
            }

            //vm.text1 += data

        });
        x.on('error', (error) => {
            //vm.ts('有错误请看日志')
            //document.getElementById("arduinoLog").innerText = error
        });
    }
    let port1
    const vm = new Vue({
        el: "#app",
        data: {
            active: 0,
            text: "",
            leapCq: "./images/bu.png",
            controller: null,
            thumb: 0,
            indexFinger: 0,
            middleFinger: 0,
            ringFinger: 0,
            pinky: 0,
            mess: "leap模式",
            LeapMode: 1,
            th23: 0,
            th12: 0,
            timers: null,
            port: null,
            menu: './images/menu_h_04.gif',
            song: false
        },
        async mounted() {
            let com = await this.getports()
            if (com) {
                port1 = getserial(com)
                getok(port1)
            } else {
                return
            }
            this.start()
            this.song = "./sound/restart.wav"
            this.startsong()
            //await delay(3000)
            this.initScene()
        },
        watch: {
            text(v, o) {
                let i
                let str
                switch (v) {
                    case "石头":
                        this.leapCq = "./images/shitou.png"
                        i = "0"
                        this.song = "./sound/shitou.wav"
                        break
                    case "剪刀":
                        this.leapCq = "./images/jiandao.png"
                        this.song = "./sound/jiandao.wav"
                        i = "1"
                        break
                    case "布":
                        this.leapCq = "./images/bu.png"
                        this.song = "./sound/bu.wav"
                        i = "2"
                        break
                }
                if (port1 && this.LeapMode == 1) {
                    try {
                        // let num = Math.random()
                        // if(num < 0.7 ){
                        //     this.song = "./sound/err.wav"
                        // }else {
                        //     this.song = "./sound/succ.wav"
                        //     switch(i){
                        //         case "0":
                        //             i = "2"
                        //             break;
                        //         case "1":
                        //             i = "0"
                        //             break
                        //         case "2":
                        //             i = "1"
                        //             break
                        //     }
                        // }

                        switch (i) {
                            case "0":
                                str = `100,100,100,100,100,z\n\r`;
                                break;
                            case "1":
                                str = `0,0,0,0,0,z\n\r`;
                                break
                            case "2":
                                str = `0,100,100,0,0,z\n\r`;
                                break
                        }

                        port1.write(str, (err) => {})
                        //vm.ts('发送完成')
                    } catch (err) {
                        //vm.ts('发送失败')
                        console.log(err)
                    }
                    this.startsong()
                }
            },
            LeapMode(v, o) {
                switch (v) {
                    case 0:
                        this.mess = "leap模式"
                        break
                    case 1:
                        this.mess = "猜拳模式"
                        this.menu = './images/menu_h_04.gif';
                        clearInterval(this.timers)
                        break
                    case 2:
                        this.timers = setInterval(this.wear, 100)
                        this.menu = './images/menu_h_07.gif';
                        this.mess = "舞动手指"
                        break
                }
            }
        },
        methods: {
            leapbutton() {
                if (this.LeapMode === 1) {
                    this.LeapMode = 2
                } else {
                    this.LeapMode = 1
                }

            },
            async startsong() {
                await delay(300)
                let s = document.getElementById("song").play();
            },
            restartleap() {
                location.reload();
            },
            async getports() {
                this.ports = await getport()
                return this.ports[0]
            },
            next() {
                if (this.active++ > 2) this.active = 0;
            },
            ts(message) {
                this.$notify({
                    title: '提示',
                    message: message,
                    offset: 100
                });
            },
            angle(a) {

                return Math.round(THREE.Math.radToDeg(Math.acos(a)) * 100 / 180)

            },
            wear() {
                let num = parseInt((this.th23-30)/0.5)
                if(num>100){
                    num = 100
                }else if(num <0){
                    num = 0
                }
                let str =
                    `${num},${100-this.angle(this.indexFinger)},${100-this.angle(this.middleFinger)},${100-this.angle(this.ringFinger)},${100-this.angle(this.pinky)},z\r\n`
                try {
                    port1.write(str)
                    //vm.ts('发送完成')
                } catch (err) {
                    //vm.ts('发送失败')
                    console.log(err)
                }
            },
            start() {

                var colors = [0xff0000, 0x00ff00, 0x0000ff];
                var baseBoneRotation = (new THREE.Quaternion).setFromEuler(
                    new THREE.Euler(Math.PI / 2, 0, 0)
                );
                let x = 1
                this.controller = Leap.loop({
                        background: true
                    }, {
                        hand: (hand) => {
                            if(x === 1){
                                window.hand2 = hand
                                x = 2
                            }
                            
                            this.thumb = Leap.vec3.dot(hand.direction, hand.thumb.direction)
                            this.indexFinger = Leap.vec3.dot(hand.direction, hand.indexFinger.direction)
                            this.middleFinger = Leap.vec3.dot(hand.direction, hand.middleFinger.direction)
                            this.ringFinger = Leap.vec3.dot(hand.direction, hand.ringFinger.direction)
                            this.pinky = Leap.vec3.dot(hand.direction, hand.pinky.direction)
                            if (this.indexFinger > 0.7 && this.middleFinger > 0.7 && this.ringFinger >
                                0.7 && this.pinky > 0.7) {
                                vm.text = "布"
                            } else if (this.indexFinger > 0 && this.middleFinger > 0 && this.ringFinger <
                                0 && this.pinky < 0) {
                                vm.text = "剪刀"
                            } else if (this.indexFinger < 0 && this.middleFinger < 0 && this.ringFinger <
                                0 && this.pinky < 0) {
                                vm.text = "石头"
                            }
                            this.th23 = Math.round(THREE.Math.radToDeg(Math.acos(Leap.vec3.dot(hand.direction,
                                hand.thumb.bones[2].direction()))))
                            this.th12 = 90 - Math.round(THREE.Math.radToDeg(Math.acos(Leap.vec3.dot(
                                hand.thumb.bones[3].direction(), hand.direction))))
                            this.th11 = 90 - Math.round(THREE.Math.radToDeg(Math.acos(Leap.vec3.dot(
                                hand.thumb.bones[1].direction(), hand.direction))))
                            hand.fingers.forEach(function (finger) {

                                // This is the meat of the example - Positioning `the cylinders on every frame:
                                finger.data('boneMeshes').forEach(function (mesh, i) {
                                    var bone = finger.bones[i];

                                    mesh.position.fromArray(bone.center());

                                    mesh.setRotationFromMatrix(
                                        (new THREE.Matrix4).fromArray(bone.matrix())
                                    );

                                    mesh.quaternion.multiply(baseBoneRotation);
                                });

                                finger.data('jointMeshes').forEach(function (mesh, i) {
                                    var bone = finger.bones[i];

                                    if (bone) {
                                        mesh.position.fromArray(bone.prevJoint);
                                    } else {
                                        // special case for the finger tip joint sphere:
                                        bone = finger.bones[i - 1];
                                        mesh.position.fromArray(bone.nextJoint);
                                    }

                                });

                            });

                            var armMesh = hand.data('armMesh');

                            armMesh.position.fromArray(hand.arm.center());

                            armMesh.setRotationFromMatrix(
                                (new THREE.Matrix4).fromArray(hand.arm.matrix())
                            );

                            armMesh.quaternion.multiply(baseBoneRotation);

                            armMesh.scale.x = hand.arm.width / 2;
                            armMesh.scale.z = hand.arm.width / 4;

                            renderer.render(scene, camera);

                        }
                    })
                    // these two LeapJS plugins, handHold and handEntry are available from leapjs-plugins, included above.
                    // handHold provides hand.data
                    // handEntry provides handFound/handLost events.
                    .use('handHold')
                    .use('handEntry')
                    .on('handFound', function (hand) {
                        if (vm.active < 3) {
                            return
                        }
                        hand.fingers.forEach(function (finger) {

                            var boneMeshes = [];
                            var jointMeshes = [];

                            finger.bones.forEach(function (bone) {

                                // create joints

                                // CylinderGeometry(radiusTop, radiusBottom, height, radiusSegments, heightSegments, openEnded)
                                var boneMesh = new THREE.Mesh(
                                    new THREE.CylinderGeometry(5, 5, bone.length),
                                    new THREE.MeshPhongMaterial()
                                );

                                boneMesh.material.color.setHex(0xffffff);
                                scene.add(boneMesh);
                                boneMeshes.push(boneMesh);
                            });

                            for (var i = 0; i < finger.bones.length + 1; i++) {

                                var jointMesh = new THREE.Mesh(
                                    new THREE.SphereGeometry(8),
                                    new THREE.MeshPhongMaterial()
                                );

                                jointMesh.material.color.setHex(0x0088ce);
                                scene.add(jointMesh);
                                jointMeshes.push(jointMesh);

                            }


                            finger.data('boneMeshes', boneMeshes);
                            finger.data('jointMeshes', jointMeshes);

                        });

                        if (hand.arm) { // 2.0.3+ have arm api,
                            // CylinderGeometry(radiusTop, radiusBottom, height, radiusSegments, heightSegments, openEnded)
                            var armMesh = new THREE.Mesh(
                                new THREE.CylinderGeometry(1, 1, hand.arm.length, 64),
                                new THREE.MeshPhongMaterial()
                            );

                            armMesh.material.color.setHex(0xffffff);

                            scene.add(armMesh);

                            hand.data('armMesh', armMesh);

                        }

                    })
                    .on('handLost', function (hand) {
                        if (vm.active < 3) {
                            return
                        }
                        hand.fingers.forEach(function (finger) {

                            var boneMeshes = finger.data('boneMeshes');
                            var jointMeshes = finger.data('jointMeshes');

                            boneMeshes.forEach(function (mesh) {
                                scene.remove(mesh);
                            });

                            jointMeshes.forEach(function (mesh) {
                                scene.remove(mesh);
                            });

                            finger.data({
                                boneMeshes: null,
                                boneMeshes: null
                            });

                        });

                        var armMesh = hand.data('armMesh');
                        scene.remove(armMesh);
                        hand.data('armMesh', null);

                        renderer.render(scene, camera);

                    })
                    .connect();

                // all units in mm

            },
            initScene() {
                window.scene = new THREE.Scene();
                window.renderer = new THREE.WebGLRenderer({
                    alpha: true
                });
                window.renderer.setClearColor(0xCC722E, 0.4);
                window.renderer.setSize(window.innerWidth, window.innerHeight);

                window.renderer.domElement.style.border = "1px solid red";
                window.renderer.domElement.style.width = '400px';
                window.renderer.domElement.style.height = '400px';
                //window.renderer.domElement.style.background = "#"
                document.getElementById("leapThree").appendChild(window.renderer.domElement);

                var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
                directionalLight.position.set(0, 0.5, 1);
                window.scene.add(directionalLight);

                window.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
                window.camera.position.fromArray([0, 100, 500]);
                window.camera.lookAt(new THREE.Vector3(0, 160, 0));

                //window.addEventListener('resize', function() {

                //camera.aspect = window.innerWidth / window.innerHeight;
                // camera.updateProjectionMatrix();
                //renderer.setSize(window.innerWidth, window.innerHeight);
                //renderer.render(scene, camera);

                //}, false);

                scene.add(camera);


                var geometry = new THREE.CubeGeometry(30, 45, 10);
                var material = new THREE.MeshPhongMaterial({
                    color: 0x0000cc
                });
                window.cube = new THREE.Mesh(geometry, material);
                cube.position.set(0, 0, 0);
                cube.castShadow = true;
                cube.receiveShadow = true;
                scene.add(cube);

                renderer.render(scene, camera);
                window.rotateCube = function () {
                    cube.rotation.x += 0.01;
                    cube.rotation.y += 0.02;
                    renderer.render(scene, camera);

                    window.requestAnimationFrame(window.rotateCube);
                };

                rotateCube();
                vm.stortThree()
            },
            stop() {
                window.renderer = null;
                window.scene = null
                window.camera = null
                window.cancelAnimationFrame(window.rotateCube)
                window.cube = null
                try {
                    this.controller.disconnect();
                } catch (err) {
                    console.log(err)
                }

                document.getElementById("leapThree").removeChild
                this.active = 1
            },
            inspectSever() {
                this.active = 1
            },
            stortSever() {
                this.active = 2
            },
            stortThree() {
                this.active = 3

            },
            stortChuankou() {
                if (!port1) {
                    vm.ts("请选择串口")
                    return
                }
                if (this.active == 3) {
                    this.LeapMode = 1
                    this.active = 5
                }

            },

        }
    })
</script>